package service

import (
	"context"
	"encoding/json"
	"fmt"
	grpc_auth "github.com/grpc-ecosystem/go-grpc-middleware/auth"
	"google.golang.org/grpc"
	"net"
	"os"
	"os/signal"
	"syscall"
	"week13/cmd"
	"week13/configs"
	"week13/errors"
	"week13/internal/biz/agent"
	"week13/log"
	"week13/metrics"
)
import (
	proto "week13/api/proto"
)

type AgentService struct {
}
//获取渠道信息
func (srv *AgentService)  GetAgent(ctx context.Context, request *proto.AgentRequest) (*proto.AgentResponse, error){
	resp := &proto.AgentResponse{Code: 0}
	var err error
	log.Info("%+v",request)
	if request.AgentId == 0 {
		err = errors.NewIllegalParam("参数错误")
		resp.Code = errors.Code(err)
		resp.Message = errors.Message(err)
		return resp,nil
	}
	agt, err := agent.NewAgent(request.AgentId,nil)
	if err != nil {
		log.Error("get agent err:",err.Error())
		resp.Code = errors.Code(err)
		resp.Message = errors.Message(err)
		metrics.IncrServerRequest("agent/GetAgent",resp.Code)
		return  resp, nil
	}
	if agt == nil {
		resp.Code = errors.NOFOUND
		resp.Message = errors.NOFOUNDMSG
		return resp, nil
	}
	buf, err := json.Marshal(agt.DTO)
	if err != nil {
		log.Info("transfer json data:%s,err:%s",buf,err.Error())
		resp.Code = errors.JSON_FAIL
		resp.Message = errors.JSON_FAIL_MSG
		metrics.IncrServerRequest("agent/GetAgent",errors.JSON_FAIL)
		return resp,nil
	}
	pagent := &proto.Agent{}
	err = json.Unmarshal(buf,pagent)
	if err != nil {
		log.Info("transfer json data:%s,err:%s",buf,err.Error())
		resp.Code = errors.JSON_FAIL
		resp.Message = errors.JSON_FAIL_MSG
		metrics.IncrServerRequest("agent/GetAgent",errors.JSON_FAIL)
		return resp,nil
	}
	resp.Data = pagent
	return resp, nil
}
//保存渠道信息
func (srv *AgentService)  Save(ctx context.Context, request *proto.Agent) (*proto.AgentResponse, error) {
	return nil, nil
}

type AgentServer struct {
	stop chan int
	signs chan os.Signal
	config configs.AppConfig
}

func (srv *AgentServer) Run(ctx context.Context) error  {
	listener, err := net.Listen("tcp", srv.config.Addr)
	if err != nil {
		log.Error("agent net.listen err:%v", err)
		return err
	}
	log.Info(" agent net listening %s",srv.config.Addr)
	AuthFunc := cmd.AuthFunc()
	rpcServer := grpc.NewServer(
		grpc.StreamInterceptor(grpc_auth.StreamServerInterceptor(AuthFunc)),
		grpc.UnaryInterceptor(grpc_auth.UnaryServerInterceptor(AuthFunc)),
	)
	proto.RegisterAgentSrvServer(rpcServer,&AgentService{})
	signal.Notify(srv.signs, syscall.SIGINT, syscall.SIGTERM)
	go func() {
		select {
		case <-srv.stop:
			rpcServer.Stop()
		case <-srv.signs:
			rpcServer.Stop()
		case <-ctx.Done():
			rpcServer.Stop()

		}
	}()
	fmt.Println("start agent server:",srv.config.Addr)
	err = rpcServer.Serve(listener)
	log.Error("agent grpc server err: %v", err)
	return err
}
func (srv *AgentServer) Close()  {
	close(srv.stop)
}
func NewAgentServer(config configs.AppConfig) *AgentServer{
	server := &AgentServer{}
	server.stop = make(chan int, 1)
	server.signs = make(chan os.Signal, 1)
	server.config = config
	return server
}